import numpy as np
import pandas as pd
from collections import Counter


# 1. 加载数据
def load_data(path):
    # 读取以逗号分隔的数据
    data = pd.read_csv(path, header=None)

    # 将前四列作为特征，最后一列作为标签
    X = data.iloc[:, :-1].values  # 特征
    y = data.iloc[:, -1].values  # 标签
    return X, y


# 2. 数据预处理
def train_test_split(X, y, test_size=0.2):
    indices = np.arange(X.shape[0])
    np.random.shuffle(indices)
    test_count = int(len(X) * test_size)
    test_indices = indices[:test_count]
    train_indices = indices[test_count:]
    return X[train_indices], y[train_indices], X[test_indices], y[test_indices]


# 3. KNN的实现
class KNN:
    def __init__(self, k=3):
        self.k = k

    def fit(self, X, y):
        self.X_train = X
        self.y_train = y

    def predict(self, X):
        predictions = [self._predict(x) for x in X]
        return np.array(predictions)

    def _predict(self, x):
        distances = np.sqrt(np.sum((self.X_train - x) ** 2, axis=1))
        k_indices = np.argsort(distances)[:self.k]
        k_nearest_labels = [self.y_train[i] for i in k_indices]
        most_common = Counter(k_nearest_labels).most_common(1)
        return most_common[0][0]

    # 4. 评估模型


def accuracy(y_true, y_pred):
    return np.sum(y_true == y_pred) / len(y_true)


# 主函数
if __name__ == "__main__":
    # 假设Iris数据存储在iris.data中
    file_path = 'C:\\Users\\li\\Desktop\\机器学习\\iris\\iris.data'
    X, y = load_data(file_path)

    # 划分训练集和测试集
    X_train, y_train, X_test, y_test = train_test_split(X, y)

    # 训练KNN模型
    knn = KNN(k=3)
    knn.fit(X_train, y_train)

    # 进行预测
    y_pred = knn.predict(X_test)

    # 计算准确率
    acc = accuracy(y_test, y_pred)
    print(f'准确率: {acc:.2f}')